package com.foftact.etfposition.service.impl;

import com.foftact.etfposition.ETFBlock;
import com.foftact.etfposition.mapper.ETFBlockMapper;
import com.foftact.etfposition.service.ETFBlockService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * ETF行业配置服务实现类
 */
@Service("etfBlockService")
public class ETFBlockServiceImpl implements ETFBlockService {
    private static final Logger logger = LoggerFactory.getLogger(ETFBlockServiceImpl.class);
    
    @Autowired
    private ETFBlockMapper etfBlockMapper;
    
    @Override
    @Transactional
    public int fetchAndSaveETFBlockData() {
        logger.info("开始抓取ETF行业配置数据");
        int savedCount = 0;
        try {
            // 1. 获取当前日期作为报告日期
            Date reportDate = new Date();
            Calendar cal = Calendar.getInstance();
            cal.setTime(reportDate);
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MILLISECOND, 0);
            reportDate = cal.getTime();
            
            // 2. 计算行业配置比例
            List<ETFBlock> etfBlocks = etfBlockMapper.calculateBlockRatio(reportDate);
            
            // 3. 批量保存数据（根据需求，需要先查询2年数据并更新或插入）
            if (!etfBlocks.isEmpty()) {
                // 先查询2年内的数据
                Calendar twoYearsAgo = Calendar.getInstance();
                twoYearsAgo.setTime(reportDate);
                twoYearsAgo.add(Calendar.YEAR, -2);
                Date startDate = twoYearsAgo.getTime();
                List<ETFBlock> existingBlocks = etfBlockMapper.selectByDateRange(startDate, reportDate);
                
                // 遍历计算结果，更新或插入
                for (ETFBlock block : etfBlocks) {
                    // 检查是否已存在
                    boolean exists = false;
                    for (ETFBlock existing : existingBlocks) {
                        if (existing.getBlockCode().equals(block.getBlockCode()) && 
                            existing.getReportDate().equals(block.getReportDate())) {
                            // 更新已存在的数据
                            existing.setBlockRatio(block.getBlockRatio());
                            existing.setUpdateTime(new Date());
                            etfBlockMapper.updateByBlockCodeAndReportDate(existing);
                            exists = true;
                            break;
                        }
                    }
                    
                    // 如果不存在，则插入
                    if (!exists) {
                        block.setUpdateTime(new Date());
                        etfBlockMapper.insert(block);
                    }
                }
                
                savedCount = etfBlocks.size();
                logger.info("成功保存/更新{}条ETF行业配置数据", savedCount);
            }
            
            // 4. 删除超过2年的旧数据
            int deletedCount = deleteOldData(730); // 2年约730天
            logger.info("成功删除{}条超过2年的旧数据", deletedCount);
            
        } catch (Exception e) {
            logger.error("抓取ETF行业配置数据失败", e);
            throw new RuntimeException("抓取ETF行业配置数据失败", e);
        }
        return savedCount;
    }
    
    @Override
    public int saveETFBlock(ETFBlock etfBlock) {
        if (etfBlock == null) {
            throw new IllegalArgumentException("ETF行业配置数据对象不能为空");
        }
        
        if (etfBlock.getUpdateTime() == null) {
            etfBlock.setUpdateTime(new Date());
        }
        
        return etfBlockMapper.insertOrUpdate(etfBlock);
    }
    
    @Override
    @Transactional
    public int batchSaveETFBlock(List<ETFBlock> etfBlocks) {
        if (etfBlocks == null || etfBlocks.isEmpty()) {
            throw new IllegalArgumentException("ETF行业配置数据列表不能为空");
        }
        
        Date now = new Date();
        for (ETFBlock etfBlock : etfBlocks) {
            if (etfBlock.getUpdateTime() == null) {
                etfBlock.setUpdateTime(now);
            }
        }
        
        return etfBlockMapper.batchInsert(etfBlocks);
    }
    
    @Override
    public ETFBlock getETFBlockByBlockCodeAndReportDate(String blockCode, Date reportDate) {
        if (blockCode == null || blockCode.trim().isEmpty() || reportDate == null) {
            throw new IllegalArgumentException("板块代码和报告日期不能为空");
        }
        return etfBlockMapper.selectByBlockCodeAndReportDate(blockCode, reportDate);
    }
    
    @Override
    public List<ETFBlock> getETFBlocksByReportDate(Date reportDate) {
        if (reportDate == null) {
            throw new IllegalArgumentException("报告日期不能为空");
        }
        return etfBlockMapper.selectByReportDate(reportDate);
    }
    
    @Override
    public List<ETFBlock> getETFBlocksByDateRange(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            throw new IllegalArgumentException("开始日期和结束日期不能为空");
        }
        return etfBlockMapper.selectByDateRange(startDate, endDate);
    }
    
    @Override
    public List<ETFBlock> getAllETFBlocks() {
        return etfBlockMapper.selectAll();
    }
    
    @Override
    @Transactional
    public int deleteOldData(int days) {
        if (days <= 0) {
            throw new IllegalArgumentException("天数必须大于0");
        }
        return etfBlockMapper.deleteOldData(days);
    }
    
    @Override
    @Transactional
    public int calculateAndUpdateBlockRatio(Date reportDate) {
        logger.info("开始计算ETF行业配置比例，报告日期: {}", reportDate);
        
        if (reportDate == null) {
            throw new IllegalArgumentException("报告日期不能为空");
        }
        
        try {
            // 调用Mapper中的计算方法
            List<ETFBlock> calculatedBlocks = etfBlockMapper.calculateBlockRatio(reportDate);
            
            if (!calculatedBlocks.isEmpty()) {
                Date now = new Date();
                
                // 更新或插入计算结果
                for (ETFBlock block : calculatedBlocks) {
                    block.setReportDate(reportDate);
                    block.setUpdateTime(now);
                    etfBlockMapper.insertOrUpdate(block);
                }
                
                logger.info("成功计算并更新{}条ETF行业配置数据", calculatedBlocks.size());
                return calculatedBlocks.size();
            }
        } catch (Exception e) {
            logger.error("计算ETF行业配置比例失败", e);
            throw new RuntimeException("计算ETF行业配置比例失败", e);
        }
        
        return 0;
    }
}